package com.dragon.modules.yuegou.service.impl.act;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.exception.DragonException;
import com.dragon.modules.yuegou.entity.act.GiftBagEntity;
import com.dragon.modules.yuegou.entity.coupon.CouponTemplateStockEntity;
import com.dragon.modules.yuegou.enums.OwnerType;
import com.dragon.modules.yuegou.enums.SkuType;
import com.dragon.modules.yuegou.enums.act.GiftBagProRefSkuType;
import com.dragon.modules.yuegou.enums.code.ActivityCode;
import com.dragon.modules.yuegou.enums.coupon.CouponTemplateShelfStatus;
import com.dragon.modules.yuegou.enums.coupon.CouponTemplateType;
import com.dragon.modules.yuegou.enums.product.SpuPublishStatus;
import com.dragon.modules.yuegou.enums.product.SpuShowModule;
import com.dragon.modules.yuegou.enums.product.StockChangeType;
import com.dragon.modules.yuegou.mapper.act.GiftBagMapper;
import com.dragon.modules.yuegou.model.act.GiftBag;
import com.dragon.modules.yuegou.model.act.GiftBagProRef;
import com.dragon.modules.yuegou.model.busd.District;
import com.dragon.modules.yuegou.model.coupon.CouponTemplate;
import com.dragon.modules.yuegou.model.product.Sku;
import com.dragon.modules.yuegou.model.product.Spu;
import com.dragon.modules.yuegou.service.act.GiftBagProRefService;
import com.dragon.modules.yuegou.service.act.GiftBagService;
import com.dragon.modules.yuegou.service.busd.DistrictService;
import com.dragon.modules.yuegou.service.coupon.CouponTemplateService;
import com.dragon.modules.yuegou.service.coupon.CouponTemplateStockService;
import com.dragon.modules.yuegou.service.product.SkuService;
import com.dragon.modules.yuegou.service.product.SpuService;
import com.dragon.modules.yuegou.service.product.StockService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 礼包表 服务实现
 *
 * @author pbuilder generated
 * @date 2020-08-05 15:47:18
 * @version 2.0
 */
@Service("actGiftBagService")
public class GiftBagServiceImpl
		extends ServiceImpl<GiftBagMapper, GiftBagEntity>
		implements GiftBagService {

	@Autowired
	private SpuService spuService;

	@Autowired
	private SkuService skuService;

	@Autowired
	private StockService stockService;

	@Autowired
	private CouponTemplateService couponTemplateService;

	@Autowired
	private CouponTemplateStockService couponTemplateStockService;

	@Autowired
	private DistrictService districtService;

	@Autowired
	private GiftBagProRefService giftBagProRefService;

	@Override
	@Transactional
	public GiftBag savaGiftBag(GiftBag giftBag) {
		//判断sku 是否存在
		List<GiftBagProRef> skuList = giftBag.getGiftBagProRefList().stream().filter(giftBagProRef -> giftBagProRef.getSkuType().equals(GiftBagProRefSkuType.SKU)).collect(Collectors.toList());
		List<GiftBagProRef> parkList = giftBag.getGiftBagProRefList().stream().filter(giftBagProRef -> giftBagProRef.getSkuType().equals(GiftBagProRefSkuType.PARKCOUPON)).collect(Collectors.toList());
		List<GiftBagProRef> cashList = giftBag.getGiftBagProRefList().stream().filter(giftBagProRef -> giftBagProRef.getSkuType().equals(GiftBagProRefSkuType.CASHCOUPON)).collect(Collectors.toList());

		if (CollectionUtils.isNotEmpty(skuList)){
			checkSku(giftBag,skuList);
		}
		if (CollectionUtils.isNotEmpty(parkList)){
			checkPark(parkList);
		}
		if (CollectionUtils.isNotEmpty(cashList)){
			checkCash(giftBag,cashList);
		}

		District district = districtService.getDistrictById(giftBag.getBusdId());
		//创建礼包 spu
		Spu spu = new Spu();
		spu.setGroupId(district.getGroupId());
		spu.setOwnerType(OwnerType.GROUP);
		spu.setSkuType(SkuType.GIFTBAG);
		spu.setBusdId(district.getId());
		spu.setTitle(giftBag.getBagName());
		spu.setShowModule(SpuShowModule.NOSHOW);
		spu.mainImg("https://crm-wx.oss-cn-shenzhen.aliyuncs.com/doc/1290954168843898882.jpg");
		spu.maxPrice(BigDecimal.ONE);
		spu.minPrice(BigDecimal.ZERO);
		spu.setPrice(BigDecimal.ZERO);
		spu.setMaxBuyNum(-1);
		spu.stock(giftBag.getNum());
		spuService.save(spu);

		Sku sku = new Sku();
		sku.setSkuType(SkuType.GIFTBAG);
		sku.setSpuId(spu.getId());
		sku.setOwnerType(OwnerType.GROUP);
		spu.setGroupId(district.getGroupId());
		spu.setBusdId(district.getId());
		sku.setTitle(giftBag.getBagName());
		sku.setMainImages("https://crm-wx.oss-cn-shenzhen.aliyuncs.com/doc/1290954168843898882.jpg");
		sku.setOriginalPrice(BigDecimal.ZERO);
		sku.setPrice(BigDecimal.ZERO);
		sku.setDiscountPrice(BigDecimal.ZERO);
		sku.setMaxBuyNum(-1);
		skuService.save(sku);

		// 插入库存信息
		stockService.changeTotal(sku.getId(), giftBag.getNum(), StockChangeType.INIT);

		giftBag.setSkuId(sku.getId());
		giftBag.setSpuId(spu.getId());

		giftBag.setCreatedTime(LocalDateTime.now());
		baseMapper.insert(giftBag);

		List<GiftBagProRef> allList = new ArrayList<>();
		allList.addAll(skuList);
		allList.addAll(parkList);
		allList.addAll(cashList);

		allList.stream().forEach(giftBagProRef -> {
			giftBagProRef.setGiftBagId(giftBag.getId());
			giftBagProRefService.save(giftBagProRef);
		});
		return giftBag;

	}

	private List<CouponTemplate> checkCash(GiftBag giftBag, List<GiftBagProRef> cashList) {
		return cashList.stream().map(giftBagProRef -> setCouponTemplate(giftBag,giftBagProRef)).collect(Collectors.toList());
	}

	private CouponTemplate setCouponTemplate(GiftBag giftBag,GiftBagProRef giftBagProRef){
		CouponTemplate couponTemplate = couponTemplateService.detail(giftBagProRef.getTemplateId());
		if (couponTemplate ==null){
			throw new DragonException(ActivityCode.CASH_COUPON_NOT_EXIST);
		}
		if (!couponTemplate.getType().equals(CouponTemplateType.CASH)){
			throw new DragonException(ActivityCode.CASH_COUPON_NOT_EXIST);
		}
		if (!CouponTemplateShelfStatus.OFF_SHELF.equals(couponTemplate.getShelfStatus())){
			throw new DragonException(ActivityCode.SKU_NOT_LOWER.getCode(),String.format(ActivityCode.SKU_NOT_LOWER.getMessage(),couponTemplate.getTitle()));
		}
		CouponTemplateStockEntity couponTemplateStock = couponTemplateStockService.getById(couponTemplate.getId());
		if((giftBag.getNum() * giftBagProRef.getNum()) > couponTemplateStock.getStockSurplus()){
			throw new DragonException(ActivityCode.STOCK_IS_LESS.getCode(),String.format(ActivityCode.STOCK_IS_LESS.getMessage(),couponTemplate.getTitle()));
		}
		giftBagProRef.setTitle(couponTemplate.getTitle());
		return  couponTemplate;
	}

	private List<CouponTemplate> checkPark(List<GiftBagProRef> parkList) {
		return parkList.stream().map(this::setParkCouponTemplate).collect(Collectors.toList());
	}
	private CouponTemplate setParkCouponTemplate(GiftBagProRef giftBagProRef){
		CouponTemplate couponTemplate = couponTemplateService.detail(giftBagProRef.getTemplateId());
		if (couponTemplate ==null){
			throw new DragonException(ActivityCode.PARK_COUPON_NOT_EXIST);
		}
		if (!couponTemplate.getType().equals(CouponTemplateType.PARK)){
			throw new DragonException(ActivityCode.PARK_COUPON_NOT_EXIST);
		}
		giftBagProRef.setTitle(couponTemplate.getTitle());
		return  couponTemplate;
	}

	private List<Sku> checkSku(GiftBag giftBag,List<GiftBagProRef> skuList){
		return skuList.stream().map(giftBagProRef -> setSku(giftBag,giftBagProRef)).collect(Collectors.toList());
	}

	private Sku setSku(GiftBag giftBag,GiftBagProRef giftBagProRef){
		Sku sku = skuService.getSkuDetail(giftBagProRef.getSkuId());
		if (sku ==null){
			throw new DragonException(ActivityCode.SKU_NOT_EXIST);
		}
		if (sku.getSpu() ==null){
			throw new DragonException(ActivityCode.SKU_NOT_EXIST);
		}
		if (!SpuPublishStatus.LOWER.equals(sku.getSpu().getPublishStatus())){
			throw new DragonException(ActivityCode.SKU_NOT_LOWER.getCode(),String.format(ActivityCode.SKU_NOT_LOWER.getMessage(),sku.getTitle()));
		}
		if (sku.getStock() ==null){
			sku.setStock(stockService.getStockInfoBySkuId(sku.getId()));
		}

		if((giftBag.getNum() * giftBagProRef.getNum()) > sku.getStock().getStock()){
			throw new DragonException(ActivityCode.STOCK_IS_LESS.getCode(),String.format(ActivityCode.STOCK_IS_LESS.getMessage(),sku.getTitle()));
		}
		giftBagProRef.setSpuId(sku.getSpuId());
		giftBagProRef.setTitle(sku.getTitle());
		return sku;
	}

}